package com.sq.partner.manager.service.impl.credit;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.ui.ModelMap;

import com.sq.partner.manager.common.Constants;
import com.sq.partner.manager.common.DictCache;
import com.sq.partner.manager.common.Result;
import com.sq.partner.manager.dao.CoinFeeConfigDao;
import com.sq.partner.manager.dao.ICoreDeptDao;
import com.sq.partner.manager.dao.IGatewayAgentInfoMtDao;
import com.sq.partner.manager.dao.IGatewayAgentInfoRelaDao;
import com.sq.partner.manager.dao.IGatewayChannelInfoConfigDao;
import com.sq.partner.manager.dao.ITradPlanGroupDao;
import com.sq.partner.manager.dao.TradSmsTemplateDao;
import com.sq.partner.manager.dao.credit.CreditPlanDao;
import com.sq.partner.manager.dao.credit.CreditProductDao;
import com.sq.partner.manager.mybatis.model.CoreDept;
import com.sq.partner.manager.mybatis.model.CreditPlan;
import com.sq.partner.manager.mybatis.model.CreditProduct;
import com.sq.partner.manager.mybatis.model.DictDto;
import com.sq.partner.manager.mybatis.model.GatewayChannelInfo;
import com.sq.partner.manager.mybatis.model.GatewayConfig;
import com.sq.partner.manager.mybatis.model.NlifePlan;
import com.sq.partner.manager.mybatis.model.TradAgentInfo;
import com.sq.partner.manager.mybatis.model.TradAgentInfoRela;
import com.sq.partner.manager.mybatis.model.TradInsuPlanGroup;
import com.sq.partner.manager.mybatis.model.TradPlanGroup;
import com.sq.partner.manager.mybatis.model.TradSmsTemplate;
import com.sq.partner.manager.mybatis.model.credit.credit10008;
import com.sq.partner.manager.service.IGatewayChannelInfoConfigService;
import com.sq.partner.manager.service.IGatewayClearCacheManager;
import com.sq.partner.manager.service.IGatewayConfigService;
import com.sq.partner.manager.service.ITradInsuPlanGroupService;
import com.sq.partner.manager.service.credit.CreditPlanService;
import com.sq.partner.manager.util.LogUtil;
import com.sq.partner.manager.util.Page;
import com.sq.partner.manager.util.StrUtil;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
@Service
public class CreditPlanServiceImpl implements CreditPlanService {
	private static Logger logger = LogUtil.getLog(CreditPlanServiceImpl.class);
	@Resource
	private CreditPlanDao creditPlanDao;
	
	@Resource
	private CreditProductDao creditProdDao;
	
	@Resource
	private IGatewayChannelInfoConfigDao channelInfoDao;
	
	@Resource
	private TradSmsTemplateDao tradSmsTemplateDao;
	
	@Resource
	private  IGatewayConfigService  gatewayConfigService;
	
	@Resource
	private IGatewayAgentInfoMtDao agentInfoDao;
	
	@Resource
	private IGatewayAgentInfoRelaDao agentInfoRelaDao;
	
	@Resource
	private IGatewayClearCacheManager gatewayClearCacheManager;
	
	@Resource
	ICoreDeptDao deptDao;
	
	@Resource
	ITradPlanGroupDao planGroupDao;
	
	@Resource
	private ITradInsuPlanGroupService insuPlanGroupService;
	
	@Resource
	private IGatewayChannelInfoConfigService channelInfoConfigService;
	
	@Resource
	private CoinFeeConfigDao coinFeeConfigDao;
	
	@Override
	public Page<GatewayChannelInfo> queryChannelInfoPageByCriteria(
			Page<GatewayChannelInfo> page) throws Exception {
		page = channelInfoDao.getListByDept(page);
		
		return page;
	}
	@Override
	public Page<Map<String, Object>> queryPlanListByCriteria(
			Page<Map<String, Object>> page) throws Exception {
		return creditPlanDao.queryPageByCriteria(page);
	}
	@Override
	public void toAddCreditPlan(ModelMap modelMap) throws Exception {
		//页面初始化加载字典表数据
		loadDictDataBeforeAddOrEdit(modelMap);
	}
	/**
	 * 新增 或 编辑 页面跳转前 往modelMap中存放字典表数据
	 * @param modelMap
	 * @throws Exception
	 */
	private void loadDictDataBeforeAddOrEdit(ModelMap modelMap) throws Exception{
		//新业务来源
		List<DictDto> newBSList  = DictCache.getDict(Constants.DICT_NEW_BUSINESS_SOURCE);
		//归属渠道
		List<DictDto> belongToChannelList = DictCache.getDict(Constants.DICT_BELONG_TO_CHANNEL);
		//渠道类型
		List<DictDto> channelTypeList = DictCache.getDict(Constants.DICT_CHANNEL_TYPE);
		//初始化承保短信模板
		List<TradSmsTemplate> messageList = tradSmsTemplateDao.queryTrade(Constants.MESSAGETEMPLATE_TYPE);
		//初始化方案销售类型
		List<DictDto> agentTypes = DictCache.getDict(Constants.DICT_AGENT_TYPE);
		//电子保单文件方式
		List<DictDto> fileTypes = DictCache.getDict(Constants.DICT_FILE_TYPE);
		/**方案号生成规则*/
		GatewayConfig gatewayConfig=gatewayConfigService.queryConfigByName(Constants.PTN_ENV);
		/**只有st显示不分大小写*/
		if(gatewayConfig!=null&&"ST".equalsIgnoreCase(gatewayConfig.getConfigValue())){
			modelMap.put("ptnEnv", "display:''");
		}else{
			modelMap.put("ptnEnv", "display:none");
		}
		modelMap.put("newBSList", newBSList);
		modelMap.put("belongToChannelList", belongToChannelList);
		modelMap.put("channelTypeList", channelTypeList);
		modelMap.put("messageList", messageList);
		modelMap.put("agentTypes", agentTypes);
		modelMap.put("fileTypes", fileTypes);
	}
	
	@Override
	public Map<String, Object> loadCreditPlan(String plan_code) throws Exception {
		Map<String,Object> map = new HashMap<String, Object>();

		CreditPlan creditPlan = creditPlanDao.queryById(plan_code);
		CreditProduct creditProd = creditProdDao.queryProdInfoById(creditPlan.getProd_code());
		map.put("creditPlan", creditPlan);
		map.put("creditProd", creditProd);

		String agentType= creditPlan.getAgent_type();
		//3 个人  4总对总
		if("3".equals(agentType) || "4".equals(agentType) ||"5".equals(agentType)||"7".equals(agentType)){
			
			List<Map> agentInfoList = agentInfoRelaDao.queryAgentInfoByInsuPlanNo(plan_code);
			map.put("agentInfoList", agentInfoList);
		}
		GatewayChannelInfo info=channelInfoConfigService.queryChannelInfoByChannelCode(creditPlan.getPartner_code());
		map.put("thirdPlan", info.getIsThirdPlan());
		return map;
	}
	@Override
	public credit10008 queryCustBy(credit10008 credit10008,String href) throws Exception {
		return creditPlanDao.queryCustBy(credit10008,href);
	}
	@Override
	public Result updateAgentInfoRela(String agent_type, List<String> list,
			Long userid, String plan_code, String agentInfoListStr)throws Exception {
			//1、合作伙伴代理3、个人代理4、总对总代理5、联合代理
			//创建一个JsonParser
			JsonParser parser = new JsonParser();
			//通过JsonParser对象可以把json格式的字符串解析成一个JsonElement对象
			JsonElement jsonElement = parser.parse(agentInfoListStr);
			//把JsonElement对象转换成JsonArray
			JsonArray jsonArray = null;
			if(jsonElement.isJsonArray()){
				jsonArray = jsonElement.getAsJsonArray();
			}
			StringBuilder ids = new StringBuilder();
			String idStr = "";
			for (JsonElement je : jsonArray) {
				if(je.getAsJsonObject().get("id")!=null){
					String id =je.getAsJsonObject().get("id").getAsString();
					ids.append(id);
					ids.append(",");
				}
			}
			if(ids.length() > 0){
				idStr=ids.substring(0, ids.length()-1);
			}
			
			agentInfoRelaDao.delTradAgentInfoRelaByInsuplannoAndAgentIds(plan_code, idStr);
			
			boolean flag = false;
			for (JsonElement je : jsonArray) {
				String id ="";
				if(je.getAsJsonObject().get("id")!=null){
					id =je.getAsJsonObject().get("id").getAsString();
				}
				String commRate=je.getAsJsonObject().get("commRate").getAsString();
				if(StrUtil.isNotEmpty(id)){
					TradAgentInfoRela agentInfoRela =new TradAgentInfoRela();
					agentInfoRela.setAgentInfoId(Long.valueOf(id));
					agentInfoRela.setInsuPlanNo(plan_code);
					if(StrUtil.isNotEmpty(commRate)){
						BigDecimal bigDecimal = new BigDecimal(commRate);
						bigDecimal = bigDecimal.setScale(6, BigDecimal.ROUND_HALF_UP); 
						agentInfoRela.setCommRate(bigDecimal);
					}
					agentInfoRela.setOperTime(new Date());
					agentInfoRela.setOperUser(userid);
					flag = agentInfoRelaDao.addOrUpdateTradAgentInfoRela(agentInfoRela);
				}
			}
			if(flag){
				//清除缓存
				gatewayClearCacheManager.clearCreditCacheInfoManager();
				return Result.success("更新成功");
			}
			return Result.error("更新失败");
	}
	
	
	@Override
	public Page<CreditProduct> queryCreditProdPageByCriteria(Page<CreditProduct> page)
			throws Exception {
		page = creditProdDao.queryPage(page);
		return page;
	}

	@Override
	public Page<CoreDept> queryDeptPageByCriteria(Page<CoreDept> page)
			throws Exception {
		String partnerNo = page.getObj()==null?"":page.getObj().toString();
		page = deptDao.queryCoreDeptPage(page,partnerNo);
		return page;
	}
	
	@Override
	public Page<Map<String, Object>> queryAgentInfoPageByCriteria(
			Page<Map<String, Object>> page, String agent_type) throws Exception {
		
		if(agent_type.equals("3")){
			page = agentInfoDao.queryAgentInfoWithUserPageByCriteria(page);
		}else if(agent_type.equals("4")){
			page = creditPlanDao.queryAgentInfoWithChannelPageByCriteria(page);
		}else if(agent_type.equals("5")){
			page = agentInfoDao.queryAgentInfoWithCombinedPageByCriteria1(page);
		}else if(agent_type.equals("7")){
			page = agentInfoDao.queryAgentInfoWithUserPageByCriteria(page);
		}
		return page;
	}
	
	@Override
	public Page<Map<String, Object>> queryAgentInfoZon4PageByCriteria(
			Page<Map<String, Object>> page) throws Exception {
		return agentInfoRelaDao.queryZonAgentInfoRelaWithPageByCriteria(page);
	}
	
	@Override
	public Result addZonTradInfo(List<TradAgentInfoRela> list,Map<String, Object> map,boolean isTradSale)
			throws Exception {
		agentInfoRelaDao.delZonTradInfo(map);
		agentInfoRelaDao.addZonTradInfo(list);
		return Result.success("配置成功");
	}
	
	@Override
	public Result addCreditPlan(CreditPlan creditPlan,CreditProduct creditProd) throws Exception {
		//产品销售类型为代理类型
		String state = creditPlan.getStatus();
		String agentType = creditPlan.getAgent_type();
		if("3".equals(agentType) || "4".equals(agentType)){
			if("1".equals(state)){
				return Result.error("方案添加时，产品销售类型为代理类型则方案不能置为有效状态");
			}
		}
		String plan_code="";
		/**根据是否上线产品生成方案号*/
		if(creditPlan.getIsProprod()){
			plan_code= creditPlanDao.queryNextPlanNo("CD");
		}else{
			plan_code= creditPlanDao.queryNextPlanNo("CRED");
		}
		creditPlan.setPlan_code(plan_code);
		boolean flag = creditPlanDao.add(creditPlan);
		//清除缓存
		gatewayClearCacheManager.clearCreditCacheInfoManager();
		
		if(flag){
			logger.info("==========================添加投保方案成功=============================");

			//根据方案对应的产品的产品类型，查询相应方案组信息,将该方案和方案组信息维护到方案与方案组关联表
			TradPlanGroup planGroup = new TradPlanGroup();
			planGroup.setProdType(creditProd.getProdType());
			planGroup = planGroupDao.queryTradPlanGroupID(planGroup);
			
			//维护方案与方案组关联表
			if(planGroup != null){
				TradInsuPlanGroup group = new TradInsuPlanGroup();
				group.setInsuPlanNumber(creditPlan.getPlan_code());
				group.setPlanGroupId(StrUtil.getVal(planGroup.getGroupId()));
				group.setRequired("0");
				boolean f = insuPlanGroupService.addTradInsuPlanGroup(group);
				
				if(!f){return Result.error("维护方案与方案组关联出错");}
			}
			Map<String,String> returnMap = new HashMap<String,String>();
			returnMap.put("plan_code", plan_code);
			returnMap.put("agent_type", creditPlan.getAgent_type());
			return Result.successAndData("添加成功",returnMap);
		}else{
			return Result.error("添加失败");
		}
	}
	
	@Override
	public Result copyAddCreditPlan(String oldPlanNo,String oldPartnerNo, String oldAgentType, CreditPlan creditPlan,CreditProduct creditProd)
			throws Exception {
		
		boolean isCopyTradAgentInfoRela = false;
		
		//产品销售类型为代理类型
		String state = creditPlan.getStatus();
		String partnerNo = creditPlan.getPartner_code();
		String agentType = creditPlan.getAgent_type();
		if("3".equals(agentType) || "4".equals(agentType)){
			if("1".equals(state)){
				if(agentType.equals(oldAgentType) && partnerNo.equals(oldPartnerNo)){
					List<Map> list = agentInfoRelaDao.queryAgentInfoByInsuPlanNo(oldPlanNo);
					if(list==null||list.isEmpty()){
						return Result.error("原方案未配置代理信息,该方案不能置为有效");
					}else{
						isCopyTradAgentInfoRela = true;
					}
				}else{
					return Result.error("产品销售类型更改或合作伙伴更改,该方案不能置为有效");
				}
			}
		}
		String plan_code ="";
		if(creditPlan.getIsProprod()){
			plan_code = creditPlanDao.queryNextPlanNo("CD");
		}else{
			plan_code = creditPlanDao.queryNextPlanNo("CRED");
		}
		creditPlan.setPlan_code(plan_code);
		boolean flag = creditPlanDao.add(creditPlan);
		
		if(isCopyTradAgentInfoRela){
			agentInfoRelaDao.copyTradAgentInfoRela(plan_code, oldPlanNo);
		}
		
		//清除缓存
		gatewayClearCacheManager.clearCreditCacheInfoManager();
		
		if(flag){
			logger.info("==========================添加投保方案成功=============================");

			//根据方案对应的产品的产品类型，查询相应方案组信息,将该方案和方案组信息维护到方案与方案组关联表
			TradPlanGroup planGroup = new TradPlanGroup();
			planGroup.setProdType(creditProd.getProdType());
			planGroup = planGroupDao.queryTradPlanGroupID(planGroup);
			
			//维护方案与方案组关联表
			if(planGroup != null){
				TradInsuPlanGroup group = new TradInsuPlanGroup();
				group.setInsuPlanNumber(creditPlan.getPlan_code());
				group.setPlanGroupId(StrUtil.getVal(planGroup.getGroupId()));
				group.setRequired("0");
				boolean f = insuPlanGroupService.addTradInsuPlanGroup(group);
				
				if(!f){return Result.error("维护方案与方案组关联出错");}
			}
			Map<String,String> returnMap = new HashMap<String,String>();
			returnMap.put("plan_code", plan_code);
			returnMap.put("agent_type", creditPlan.getAgent_type());
			return Result.successAndData("添加成功",returnMap);
		}else{
			return Result.error("添加失败");
		}
	}
	
	@Override
	public Result updateCreditPlan(CreditPlan creditPlan,CreditProduct creditProd)
			throws Exception {
		//产品销售类型为代理类型
		String plan_code = creditPlan.getPlan_code();
		String state = creditPlan.getStatus();
		String agentType = creditPlan.getAgent_type();
		if("3".equals(agentType) || "4".equals(agentType)){
			if("1".equals(state)){
				List<Map> list = agentInfoRelaDao.queryAgentInfoByInsuPlanNo(plan_code);
				if(list==null||list.isEmpty()){
					return Result.error("代理信息为空 时不能将方案状态置为有效,请配置代理信息");
				}
			}
		}
		
		boolean flag = creditPlanDao.update(creditPlan);
		//清除缓存
		gatewayClearCacheManager.clearCreditCacheInfoManager();
		if(flag){
			logger.info("==========================更新投保方案成功=============================");
			CreditPlan creditPlan_current = creditPlanDao.queryById(plan_code);
			//如果此方案修改了产品，则同步更改方案与方案组关联，否则不做修改
			if(!creditPlan_current.getProd_code().equals(creditPlan.getProd_code())){
				//根据方案对应的产品的产品类型，查询相应方案组信息,将该方案和方案组信息维护到方案与方案组关联表
				TradPlanGroup planGroup = new TradPlanGroup();
				planGroup.setProdType(creditProd.getProdType());
				planGroup = planGroupDao.queryTradPlanGroupID(planGroup);
				
				//维护方案与方案组关联表
				if(planGroup != null){
					TradInsuPlanGroup group = new TradInsuPlanGroup();
					group.setInsuPlanNumber(plan_code);
					group.setPlanGroupId(StrUtil.getVal(planGroup.getGroupId()));
					group.setRequired("0");
					boolean f =insuPlanGroupService.updateTradInsuPlanGroup(group);
					
					if(!f){return Result.error("维护方案与方案组关联出错");}
				}
			}
			return Result.success("修改成功");
		}else{
			return Result.error("修改失败");
		}
	}
	
	@Override
	public void toEditCreditPlan(ModelMap modelMap,String plan_code) throws Exception {
		//页面初始化加载字典表数据
		loadDictDataBeforeAddOrEdit(modelMap);
		
		modelMap.put("plan_code", plan_code);
	}
	
	@Override
	public void toCopyAddCreditPlan(ModelMap modelMap,String plan_code) throws Exception {
		//页面初始化加载字典表数据
		loadDictDataBeforeAddOrEdit(modelMap);
		modelMap.put("oldplan_code", plan_code);
	}
	
	@Override
	public Result delCreditPlan(CreditPlan creditPlan) throws Exception {
		creditPlan = creditPlanDao.queryById(creditPlan.getPlan_code());
		String status = creditPlan.getStatus();
		if(1 == Integer.parseInt(status)){
			return Result.error("该方案状态为有效，不能删除");
		}else{
			String agentType = creditPlan.getAgent_type();
			//1、合作伙伴代理3、个人代理4、总对总代理
			if("3".equals(agentType)||"4".equals(agentType)){
				//根据方案号删除方案下面配置的代理信息
				agentInfoRelaDao.delTradAgentInfoRelaByPlanNo(creditPlan.getPlan_code());
			}
			boolean flag = creditPlanDao.delById(creditPlan.getPlan_code());
			//清除缓存
			channelInfoConfigService.clearAllCacheByChannelCode(creditPlan.getPartner_code());
		
			if(flag){
				//删除方案组关联
				insuPlanGroupService.deleteTradInsuPlanGroupByInsuPlanNo(creditPlan.getPlan_code());
				return Result.success("删除成功");
			}else{
				return Result.error("删除失败");
			}
		}
	}
	@Override
	public CreditPlan queryById(String plan_code) throws Exception {
		return creditPlanDao.queryById(plan_code);
	}
	
	@Override
	public Page<Map<String, Object>> queryAgentInfoRelaPageByCriteria(
			Page<Map<String, Object>> page, String agentType) throws Exception {
		
		if(agentType.equals("3")){
			page = agentInfoRelaDao.queryAgentInfoRelaWithUserPageByCriteria(page);
		}else if(agentType.equals("4")){
			page = agentInfoRelaDao.queryAgentInfoRelaWithChannelPageByCriteria(page);
		}else if(agentType.equals("5")){
			page.getMap().put("parentChannelCode", null);
			page = agentInfoRelaDao.queryAgentInfoRelaWithCombinedPageByCriteria(page);
		}else if(agentType.equals("6")){
			page = coinFeeConfigDao.queryCoinsByPage(page);
		}else if(agentType.equals("7")){
			page = agentInfoRelaDao.queryAgentInfoRelaWithUserPageByCriteria(page);
		}
		return page;
	}
	
	@Override
	public Boolean delZonTradInfo(Map<String, Object> map) throws Exception {
			return agentInfoRelaDao.delZonTradInfo(map);
	}
	@Override
	public boolean queryByProdId(String prod_code) throws Exception {
		return creditPlanDao.queryByProdId(prod_code);
	}
	
	@Override
	public List<CreditPlan> impCreditPlan(Map<String, Object> map)
			throws Exception {
		return creditPlanDao.impCreditPlan(map);
	}
}
